﻿using System;

namespace DeepZoomPivotConstructor.PivotLib
{
    /// <summary>
    /// A small bit of pivot meta data (a new item).
    /// Of some type...
    /// </summary>
    public abstract class PivotMetadataBase
    {
        public string Name { get; private set; }

        /// <summary>
        /// Create the base class for the pivot meta data
        /// </summary>
        /// <param name="name"></param>
        protected PivotMetadataBase(string name)
        {
            if (name == null || name.Length == 0)
            {
                throw new ArgumentException("name of pivot meta data can't be null or empty!", "name");
            }
            Name = name;
        }

        /// <summary>
        /// Returns an object that can be used in the
        /// actual facet.
        /// </summary>
        /// <returns></returns>
        public abstract object ToFacetInfo();
    }

    /// <summary>
    /// Subclass that holds onto a url for its meta data.
    /// </summary>
    public class PivotMetadataURL : PivotMetadataBase
    {
        public Uri LinkUri { get; set; }
        public string LinkText { get; set; }

        public PivotMetadataURL(string name, string linkName, Uri linkDestination)
            : base(name)
        {
            if (linkName == null || linkName.Length == 0)
            {
                throw new ArgumentException("The link name of the url can't be null or empty!", "linkName");
            }
            if (linkDestination == null)
            {
                throw new ArgumentException("The uri of the pivot link metadata can't be null!", "linkDestination");
            }

            this.LinkText = linkName;
            this.LinkUri = linkDestination;
        }

        /// <summary>
        /// Returns the facet for the Link.
        /// </summary>
        /// <returns></returns>
        public override object ToFacetInfo()
        {
            PivotSchema.linkType lt = new PivotSchema.linkType();
            lt.Name = LinkText;
            lt.Href = LinkUri.OriginalString;
            return lt;
        }
    }

    /// <summary>
    /// Subclass that holds onto a number for its meta data.
    /// </summary>
    public class PivotMetadataNumber : PivotMetadataBase
    {
        public decimal Value { get; set; }

        public PivotMetadataNumber(string name, decimal value)
            : base(name)
        {
            Value = value;
        }

        /// <summary>
        /// Convert to a number. Numbers that are just a small bit away from zero
        /// will get turncated due to a bug in the PV generation collection.
        /// </summary>
        /// <returns></returns>
        public override object ToFacetInfo()
        {
            PivotSchema.numberType result = new PivotSchema.numberType();
            var closestInt = Math.Round(Value, 0);
            if (Math.Abs(closestInt - Value) < (decimal)0.00005)
            {
                result.Value = closestInt;
            }
            else
            {
                result.Value = Value;
            }

            return result;
        }
    }

    /// <summary>
    /// Subclass that holds onto a string for its meta data.
    /// </summary>
    public class PivotMetadataString : PivotMetadataBase
    {
        public string Value { get; set; }

        public PivotMetadataString(string name, string stringValue)
            : base(name)
        {
            if (stringValue == null || stringValue.Length == 0)
            {
                throw new ArgumentException("The string value of the pivot string meta data can't be null!", "stringValue");
            }
            this.Value = stringValue;
        }

        public override object ToFacetInfo()
        {
            PivotSchema.stringType str = new PivotSchema.stringType();
            str.Value = Value;
            return str;
        }
    }

    /// <summary>
    /// Subclass that holds onto a DateTime for its meta data.
    /// </summary>
    public class PivotMetadataDateTime : PivotMetadataBase
    {
        public DateTime TheTime { get; set; }

        public PivotMetadataDateTime(string name, DateTime dateTime)
            : base(name)
        {
            this.TheTime = dateTime;
        }

        public override object ToFacetInfo()
        {
            PivotSchema.dateTimeType dtr = new PivotSchema.dateTimeType();
            dtr.Value = TheTime;
            return dtr;
        }
    }

}
